home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / RKMLibsPrgs / graphics_libraries / sprites_bobs / animtools.c < prev    next >
C/C++ Source or Header  |  1992-09-03  |  16KB  |  399 lines

  1. /* animtools.c
  2. **
  3. ** This file is a collection of tools which are used with the VSprite, Bob and Animation
  4. ** system software. It is intended as a useful EXAMPLE, and while it shows what must be
  5. ** done, it is not the only way to do it.  If Not Enough Memory, or error return, each
  6. ** cleans up after itself before returning.  NOTE that these routines assume a very specific
  7. ** structure to the GEL lists.  Make sure that you use the correct pairs together
  8. ** (i.e. makeOb()/freeOb(), etc.)
  9. **
  10. ** Compile with SAS/C 5.10b: lc -b1 -cfist -v -oanimtools.o animtools.c
  11.  
  12.  
  13. Copyright (c) 1992 Commodore-Amiga, Inc.
  14.  
  15. This example is provided in electronic form by Commodore-Amiga, Inc. for
  16. use with the "Amiga ROM Kernel Reference Manual: Libraries", 3rd Edition,
  17. published by Addison-Wesley (ISBN 0-201-56774-1).
  18.  
  19. The "Amiga ROM Kernel Reference Manual: Libraries" contains additional
  20. information on the correct usage of the techniques and operating system
  21. functions presented in these examples.  The source and executable code
  22. of these examples may only be distributed in free electronic form, via
  23. bulletin board or as part of a fully non-commercial and freely
  24. redistributable diskette.  Both the source and executable code (including
  25. comments) must be included, without modification, in any copy.  This
  26. example may not be published in printed form or distributed with any
  27. commercial product.  However, the programming techniques and support
  28. routines set forth in these examples may be used in the development
  29. of original executable software products for Commodore Amiga computers.
  30.  
  31. All other rights reserved.
  32.  
  33. This example is provided "as-is" and is subject to change; no
  34. warranties are made.  All use is at your own risk. No liability or
  35. responsibility is assumed.
  36. */
  37.  
  38. #include <exec/types.h>
  39. #include <exec/memory.h>
  40. #include <graphics/gfx.h>
  41. #include <graphics/gels.h>
  42. #include <graphics/clip.h>
  43. #include <graphics/rastport.h>
  44. #include <graphics/view.h>
  45. #include <graphics/gfxbase.h>
  46. #include "animtools.h"
  47.  
  48. /* Setup the GELs system.  After this call is made you can use VSprites, Bobs, AnimComps
  49. ** and AnimObs.  Note that this links the GelsInfo structure into the RastPort, and calls
  50. ** InitGels().  It uses information in your RastPort structure to establish boundary collision
  51. ** defaults at the outer edges of the raster.  This routine sets up for everything - collision
  52. ** detection and all. You must already have run LoadView before ReadyGelSys is called.
  53. */
  54. struct GelsInfo *setupGelSys(struct RastPort *rPort, BYTE reserved)
  55. {
  56. struct GelsInfo *gInfo;
  57. struct VSprite  *vsHead;
  58. struct VSprite  *vsTail;
  59.  
  60. if (NULL != (gInfo = (struct GelsInfo *)AllocMem(sizeof(struct GelsInfo), MEMF_CLEAR)))
  61.         {
  62.         if (NULL != (gInfo->nextLine = (WORD *)AllocMem(sizeof(WORD) * 8, MEMF_CLEAR)))
  63.             {
  64.             if (NULL != (gInfo->lastColor = (WORD **)AllocMem(sizeof(LONG) * 8, MEMF_CLEAR)))
  65.                 {
  66.                 if (NULL != (gInfo->collHandler = (struct collTable *)
  67.                         AllocMem(sizeof(struct collTable),MEMF_CLEAR)))
  68.                     {
  69.                     if (NULL != (vsHead = (struct VSprite *)
  70.                             AllocMem((LONG)sizeof(struct VSprite), MEMF_CLEAR)))
  71.                         {
  72.                         if (NULL != (vsTail = (struct VSprite *)
  73.                                 AllocMem(sizeof(struct VSprite), MEMF_CLEAR)))
  74.                             {
  75.                             gInfo->sprRsrvd   = reserved;
  76.                             /* Set left- and top-most to 1 to better keep items */
  77.                             /* inside the display boundaries.                   */
  78.                             gInfo->leftmost   = gInfo->topmost    = 1;
  79.                             gInfo->rightmost  = (rPort->BitMap->BytesPerRow << 3) - 1;
  80.                             gInfo->bottommost = rPort->BitMap->Rows - 1;
  81.                             rPort->GelsInfo = gInfo;
  82.                             InitGels(vsHead, vsTail, gInfo);
  83.                             return(gInfo);
  84.                             }
  85.                         FreeMem(vsHead, (LONG)sizeof(*vsHead));
  86.                         }
  87.                     FreeMem(gInfo->collHandler, (LONG)sizeof(struct collTable));
  88.                     }
  89.                 FreeMem(gInfo->lastColor, (LONG)sizeof(LONG) * 8);
  90.                 }
  91.             FreeMem(gInfo->nextLine, (LONG)sizeof(WORD) * 8);
  92.             }
  93.         FreeMem(gInfo, (LONG)sizeof(*gInfo));
  94.         }
  95. return(NULL);
  96. }
  97.  
  98.  
  99. /* Free all of the stuff allocated by setupGelSys().  Only call this routine if
  100. ** setupGelSys() returned successfully.  The GelsInfo structure is the one returned
  101. ** by setupGelSys().   It also unlinks the GelsInfo from the RastPort.
  102. */
  103. VOID cleanupGelSys(struct GelsInfo *gInfo, struct RastPort *rPort)
  104. {
  105. rPort->GelsInfo = NULL;
  106. FreeMem(gInfo->collHandler, (LONG)sizeof(struct collTable));
  107. FreeMem(gInfo->lastColor, (LONG)sizeof(LONG) * 8);
  108. FreeMem(gInfo->nextLine, (LONG)sizeof(WORD) * 8);
  109. FreeMem(gInfo->gelHead, (LONG)sizeof(struct VSprite));
  110. FreeMem(gInfo->gelTail, (LONG)sizeof(struct VSprite));
  111. FreeMem(gInfo, (LONG)sizeof(*gInfo));
  112. }
  113.  
  114.  
  115. /* Create a VSprite from the information given in nVSprite.  Use freeVSprite()
  116. ** to free this GEL.
  117. */
  118. struct VSprite *makeVSprite(NEWVSPRITE *nVSprite)
  119. {
  120. struct VSprite *vsprite;
  121. LONG            line_size;
  122. LONG            plane_size;
  123.  
  124. line_size = sizeof(WORD) * nVSprite->nvs_WordWidth;
  125. plane_size = line_size * nVSprite->nvs_LineHeight;
  126.  
  127. if (NULL != (vsprite = (struct VSprite *)AllocMem((LONG)sizeof(struct VSprite), MEMF_CLEAR)))
  128.         {
  129.         if (NULL != (vsprite->BorderLine = (WORD *)AllocMem(line_size, MEMF_CHIP)))
  130.             {
  131.             if (NULL != (vsprite->CollMask = (WORD *)AllocMem(plane_size, MEMF_CHIP)))
  132.                 {
  133.                 vsprite->Y          = nVSprite->nvs_Y;
  134.                 vsprite->X          = nVSprite->nvs_X;
  135.                 vsprite->Flags      = nVSprite->nvs_Flags;
  136.                 vsprite->Width      = nVSprite->nvs_WordWidth;
  137.                 vsprite->Depth      = nVSprite->nvs_ImageDepth;
  138.                 vsprite->Height     = nVSprite->nvs_LineHeight;
  139.                 vsprite->MeMask     = nVSprite->nvs_MeMask;
  140.                 vsprite->HitMask    = nVSprite->nvs_HitMask;
  141.                 vsprite->ImageData  = nVSprite->nvs_Image;
  142.                 vsprite->SprColors  = nVSprite->nvs_ColorSet;
  143.                 vsprite->PlanePick  = vsprite->PlaneOnOff = 0x00;
  144.                 InitMasks(vsprite);
  145.                 return(vsprite);
  146.                 }
  147.             FreeMem(vsprite->BorderLine, line_size);
  148.             }
  149.         FreeMem(vsprite, (LONG)sizeof(*vsprite));
  150.         }
  151. return(NULL);
  152. }
  153.  
  154.  
  155. /* Create a Bob from the information given in nBob.  Use freeBob() to free this GEL.
  156. ** A VSprite is created for this bob.  This routine properly allocates all double
  157. ** buffered information if it is required.
  158. */
  159. struct Bob *makeBob(NEWBOB *nBob)
  160. {
  161. struct Bob         *bob;
  162. struct VSprite     *vsprite;
  163. NEWVSPRITE          nVSprite ;
  164. LONG                rassize;
  165.  
  166. rassize = (LONG)sizeof(UWORD) * nBob->nb_WordWidth * nBob->nb_LineHeight * nBob->nb_RasDepth;
  167.  
  168. if (NULL != (bob = (struct Bob *)AllocMem((LONG)sizeof(struct Bob), MEMF_CLEAR)))
  169.         {
  170.         if (NULL != (bob->SaveBuffer = (WORD *)AllocMem(rassize, MEMF_CHIP)))
  171.             {
  172.             nVSprite.nvs_WordWidth  = nBob->nb_WordWidth;
  173.             nVSprite.nvs_LineHeight = nBob->nb_LineHeight;
  174.             nVSprite.nvs_ImageDepth = nBob->nb_ImageDepth;
  175.             nVSprite.nvs_Image      = nBob->nb_Image;
  176.             nVSprite.nvs_X          = nBob->nb_X;
  177.             nVSprite.nvs_Y          = nBob->nb_Y;
  178.             nVSprite.nvs_ColorSet   = NULL;
  179.             nVSprite.nvs_Flags      = nBob->nb_BFlags;
  180.             /* Push the values into the NEWVSPRITE structure for use in makeVSprite(). */
  181.             nVSprite.nvs_MeMask     = nBob->nb_MeMask;
  182.             nVSprite.nvs_HitMask    = nBob->nb_HitMask;
  183.  
  184.             if ((vsprite = makeVSprite(&nVSprite)) != NULL)
  185.                 {
  186.                 vsprite->PlanePick = nBob->nb_PlanePick;
  187.                 vsprite->PlaneOnOff = nBob->nb_PlaneOnOff;
  188.                 vsprite->VSBob   = bob;
  189.                 bob->BobVSprite  = vsprite;
  190.                 bob->ImageShadow = vsprite->CollMask;
  191.                 bob->Flags       = 0;
  192.                 bob->Before      = NULL;
  193.                 bob->After       = NULL;
  194.                 bob->BobComp     = NULL;
  195.  
  196.                 if (nBob->nb_DBuf)
  197.                     {
  198.                     if (NULL != (bob->DBuffer = (struct DBufPacket *)
  199.                             AllocMem((LONG)sizeof(struct DBufPacket), MEMF_CLEAR)))
  200.                         {
  201.                         if (NULL != (bob->DBuffer->BufBuffer = (WORD *)AllocMem(rassize, MEMF_CHIP)))
  202.                             return(bob);
  203.                         FreeMem(bob->DBuffer, (LONG)sizeof(struct DBufPacket));
  204.                         }
  205.                     }
  206.                 else
  207.                     {
  208.                     bob->DBuffer = NULL;
  209.                     return(bob);
  210.                     }
  211.                 freeVSprite(vsprite);
  212.                 }
  213.             FreeMem(bob->SaveBuffer, rassize);
  214.             }
  215.         FreeMem(bob, (LONG)sizeof(*bob));
  216.         }
  217. return(NULL);
  218. }
  219.  
  220.  
  221. /*
  222. ** Create a Animation Component from the information given in nAnimComp and nBob.  Use
  223. ** freeComp() to free this GEL.  makeComp() calls makeBob(), and links the Bob into an AnimComp.
  224. */
  225. struct AnimComp *makeComp(NEWBOB *nBob, NEWANIMCOMP *nAnimComp)
  226. {
  227. struct Bob      *compBob;
  228. struct AnimComp *aComp;
  229.  
  230. if ((aComp = AllocMem((LONG)sizeof(struct AnimComp),MEMF_CLEAR)) != NULL)
  231.         {
  232.         if ((compBob = makeBob(nBob)) != NULL)
  233.             {
  234.             compBob->After   = compBob->Before  = NULL;
  235.             compBob->BobComp = aComp;   /* Link 'em up. */
  236.             aComp->AnimBob      = compBob;
  237.             aComp->TimeSet      = nAnimComp->nac_Time; /* Num ticks active. */
  238.             aComp->YTrans       = nAnimComp->nac_Yt; /* Offset rel to HeadOb */
  239.             aComp->XTrans       = nAnimComp->nac_Xt;
  240.             aComp->AnimCRoutine = nAnimComp->nac_Routine;
  241.             aComp->Flags        = nAnimComp->nac_CFlags;
  242.             aComp->Timer        = 0;
  243.             aComp->NextSeq      = aComp->PrevSeq  = NULL;
  244.             aComp->NextComp     = aComp->PrevComp = NULL;
  245.             aComp->HeadOb       = NULL;
  246.             return(aComp);
  247.             }
  248.         FreeMem(aComp, (LONG)sizeof(struct AnimComp));
  249.         }
  250. return(NULL);
  251. }
  252.  
  253.  
  254.  
  255. /* Create an Animation Sequence from the information given in nAnimSeq and nBob.  Use
  256. ** freeSeq() to free this GEL.  This routine creates a linked list of animation components
  257. ** which make up the animation sequence.  It links them all up, making a circular list of
  258. ** the PrevSeq and NextSeq pointers. That is to say, the first component of the sequences'
  259. ** PrevSeq points to the last component; the last component of * the sequences' NextSeq
  260. ** points back to the first component.  If dbuf is on, the underlying Bobs will be set up
  261. ** for double buffering.  If singleImage is non-zero, the pImages pointer is assumed to
  262. ** point to an array of only one image, instead of an array of 'count' images, and all
  263. ** Bobs will use the same image.
  264. */
  265. struct AnimComp *makeSeq(NEWBOB *nBob, NEWANIMSEQ *nAnimSeq)
  266. {
  267. int seq;
  268. struct AnimComp *firstCompInSeq = NULL;
  269. struct AnimComp *seqComp = NULL;
  270. struct AnimComp *lastCompMade = NULL;
  271. LONG image_size;
  272. NEWANIMCOMP nAnimComp;
  273.  
  274. /* get the initial image.  this is the only image that is used
  275. ** if nAnimSeq->nas_SingleImage is non-zero.
  276. */
  277. nBob->nb_Image = nAnimSeq->nas_Images;
  278. image_size = nBob->nb_LineHeight * nBob->nb_ImageDepth * nBob->nb_WordWidth;
  279.  
  280. /* for each comp in the sequence */
  281. for (seq = 0; seq < nAnimSeq->nas_Count; seq++)
  282.         {
  283.         nAnimComp.nac_Xt        = *(nAnimSeq->nas_Xt + seq);
  284.         nAnimComp.nac_Yt        = *(nAnimSeq->nas_Yt + seq);
  285.         nAnimComp.nac_Time      = *(nAnimSeq->nas_Times + seq);
  286.         nAnimComp.nac_Routine   = nAnimSeq->nas_Routines[seq];
  287.         nAnimComp.nac_CFlags    = nAnimSeq->nas_CFlags;
  288.         if ((seqComp = makeComp(nBob, &nAnimComp)) == NULL)
  289.             {
  290.             if (firstCompInSeq != NULL)
  291.                 freeSeq(firstCompInSeq, (LONG)nBob->nb_RasDepth);
  292.             return(NULL);
  293.             }
  294.         seqComp->HeadOb = nAnimSeq->nas_HeadOb;
  295.         /* Make a note of where the first component is. */
  296.         if (firstCompInSeq == NULL) firstCompInSeq = seqComp;
  297.         /* link the component into the list */
  298.         if (lastCompMade != NULL) lastCompMade->NextSeq = seqComp;
  299.         seqComp->NextSeq = NULL;
  300.         seqComp->PrevSeq = lastCompMade;
  301.         lastCompMade = seqComp;
  302.         /* If nAnimSeq->nas_SingleImage is zero, the image array has nAnimSeq->nas_Count images. */
  303.         if (!nAnimSeq->nas_SingleImage)
  304.             nBob->nb_Image += image_size;
  305.         }
  306. /* On The last component in the sequence, set Next/Prev to make */
  307. /* the linked list a loop of components.                        */
  308. lastCompMade->NextSeq = firstCompInSeq;
  309. firstCompInSeq->PrevSeq = lastCompMade;
  310.  
  311. return(firstCompInSeq);
  312. }
  313.  
  314.  
  315. /* Free the data created by makeVSprite().  Assumes images deallocated elsewhere. */
  316. VOID freeVSprite(struct VSprite *vsprite)
  317. {
  318. LONG    line_size;
  319. LONG    plane_size;
  320.  
  321. line_size = (LONG)sizeof(WORD) * vsprite->Width;
  322. plane_size = line_size * vsprite->Height;
  323. FreeMem(vsprite->BorderLine, line_size);
  324. FreeMem(vsprite->CollMask, plane_size);
  325. FreeMem(vsprite, (LONG)sizeof(*vsprite));
  326. }
  327.  
  328.  
  329.  
  330.  
  331. /* Free the data created by makeBob().  It's important that rasdepth match the depth you */
  332. /* passed to makeBob() when this GEL was made. Assumes images deallocated elsewhere.     */
  333. VOID freeBob(struct Bob *bob, LONG rasdepth)
  334. {
  335. LONG    rassize =  sizeof(UWORD) * bob->BobVSprite->Width * bob->BobVSprite->Height * rasdepth;
  336.  
  337. if (bob->DBuffer != NULL)
  338.         {
  339.         FreeMem(bob->DBuffer->BufBuffer, rassize);
  340.         FreeMem(bob->DBuffer, (LONG)sizeof(struct DBufPacket));
  341.         }
  342. FreeMem(bob->SaveBuffer, rassize);
  343. freeVSprite(bob->BobVSprite);
  344. FreeMem(bob, (LONG)sizeof(*bob));
  345. }
  346.  
  347.  
  348. /* Free the data created by makeComp().  It's important that rasdepth match the depth you */
  349. /* passed to makeComp() when this GEL was made. Assumes images deallocated elsewhere.    */
  350. VOID freeComp(struct AnimComp *myComp, LONG rasdepth)
  351. {
  352. freeBob(myComp->AnimBob, rasdepth);
  353. FreeMem(myComp, (LONG)sizeof(struct AnimComp));
  354. }
  355.  
  356.  
  357. /* Free the data created by makeSeq().  Complimentary to makeSeq(), this routine goes through
  358. ** the NextSeq pointers and frees the Components.  This routine only goes forward through the
  359. ** list, and so it must be passed the first component in the sequence, or the sequence must
  360. ** be circular (which is guaranteed if you use makeSeq()).  It's important that rasdepth match
  361. ** the depth you passed to makeSeq() when this GEL was made.   Assumes images deallocated elsewhere!
  362. */
  363. VOID freeSeq(struct AnimComp *headComp, LONG rasdepth)
  364. {
  365. struct AnimComp *curComp;
  366. struct AnimComp *nextComp;
  367.  
  368. /* Break the NextSeq loop, so we get a NULL at the end of the list. */
  369. headComp->PrevSeq->NextSeq = NULL;
  370.  
  371. curComp = headComp;         /* get the start of the list */
  372. while (curComp != NULL)
  373.         {
  374.         nextComp = curComp->NextSeq;
  375.         freeComp(curComp, rasdepth);
  376.         curComp = nextComp;
  377.         }
  378. }
  379.  
  380.  
  381. /* Free an animation object (list of sequences).  freeOb() goes through the NextComp
  382. ** pointers, starting at the AnimObs' HeadComp, and frees every sequence.  It only
  383. ** goes forward. It then frees the Object itself.  Assumes images deallocated elsewhere!
  384. */
  385. VOID freeOb(struct AnimOb *headOb, LONG rasdepth)
  386. {
  387. struct AnimComp *curSeq;
  388. struct AnimComp *nextSeq;
  389.  
  390. curSeq = headOb->HeadComp;          /* get the start of the list */
  391. while (curSeq != NULL)
  392.         {
  393.         nextSeq = curSeq->NextComp;
  394.         freeSeq(curSeq, rasdepth);
  395.         curSeq = nextSeq;
  396.         }
  397. FreeMem(headOb, sizeof(struct AnimOb));
  398. }
  399.